﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace PBO.Data.Util
{
    public static class DataStreamHelper
    {

        #region teamdata

        private const string KEY = "sJg/jtph3lzuhiy9EafZtw==";
        private const string IV = "k/SHDmKCLIo=";

        internal static void Encrypt(MemoryStream ms, string outPath)
        {
            var algorithm = SymmetricAlgorithm.Create("RC2");
            algorithm.Key = Convert.FromBase64String(KEY);
            algorithm.IV = Convert.FromBase64String(IV);
            using (var fs = new FileStream(outPath, FileMode.Create, FileAccess.Write))
            {
                using (var cs = new CryptoStream(fs, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    byte[] buffer = ms.GetBuffer();
                    cs.Write(buffer, 0, buffer.Length);
                }
                fs.Close();
            }
        }

        internal static MemoryStream Decrypt(FileStream stream)
        {
            var algorithm = SymmetricAlgorithm.Create("RC2");
            algorithm.Key = Convert.FromBase64String(KEY);
            algorithm.IV = Convert.FromBase64String(IV);
            byte[] buffer = new byte[2050];
            MemoryStream ms = new MemoryStream();
            if (stream.Length != 0)
            {
                using (var cs = new CryptoStream(stream, algorithm.CreateDecryptor(), CryptoStreamMode.Read))
                {
                    int num = 0;
                    do
                    {
                        num = cs.Read(buffer, 0, buffer.Length);
                        ms.Write(buffer, 0, num);
                    } while (num > 0);
                }
            }
            return ms;
        }

        internal static string ComputeHash(Stream stream)
        {
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] buffer = md5.ComputeHash(stream);
            return Convert.ToBase64String(buffer);
        }



        public static void Load(this IBinaryIO bin, Stream input)
        {
            using (var reader = new BinaryReader(input))
            {
                bin.BinaryLoad(reader);
            }
        }

        public static void Save(this IBinaryIO bin, Stream output)
        {
            using (var writer = new BinaryWriter(output))
            {
                bin.BinarySave(writer);
            }
        }

        #endregion

        #region datastream

        //public static T FromStream<T>(Stream input) where T : IDataStream
        //{
        //    var obj = Activator.CreateInstance<T>();
        //    obj.Load(input);
        //    return obj;
        //}

        //public static List<T> ReadList<T>(BinaryReader reader) where T : IDataStream
        //{
        //    int count = reader.ReadInt32();
        //    var list = new List<T>(count);
        //    for (int i = 0; i < count; i++)
        //    {
        //        var item = FromStream<T>(reader.BaseStream);
        //        list.Add(item);
        //    }
        //    return list;
        //}

        //public static void WriteList(this List<IDataStream> list, BinaryWriter writer)
        //{
        //    writer.Write(list.Count);
        //    foreach (IDataStream item in list)
        //    {
        //        item.Save(writer.BaseStream);
        //    }
        //}

        //public static T FromFile<T>(string path) where T : IDataStream
        //{
        //    T data;
        //    using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
        //    {
        //        data = FromStream<T>(stream);
        //        stream.Close();
        //    }
        //    return data;
        //}

        //public static void SaveFile(this IDataStream data, string path)
        //{
        //    using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write))
        //    {
        //        data.Save(stream);
        //        stream.Flush();
        //        stream.Close();
        //    }
        //}

        #endregion

    }
}